#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "log.hpp"

namespace server
{
    enum
    {
        USAGE_ERR = 1,
        SOCK_ERR,
        BIND_ERR,
        LISTEN_ERR
    };

    static const uint16_t gport = 8080;
    static const int gbacklog = 5;

    class CalServer
    {
    public:
        CalServer(const uint16_t &port = gport)
            : _listensock(-1), _port(port)
        {
        }

        void initServer()
        {
            // 1. 创建socket文件套接字对象
            _listensock = socket(AF_INET, SOCK_STREAM, 0);
            if (_listensock < 0)
            {
                logMessage(FATAL, "create listensock error");
                exit(SOCK_ERR);
            }
            logMessage(NORMAL, "create listensock success : %d", _listensock);

             // 2. bind绑定自己的网络信息
            struct sockaddr_in local;
            memset(&local, 0, sizeof local);

            local.sin_family = AF_INET;
            local.sin_port = htons(_port);
            local.sin_addr.s_addr = INADDR_ANY;

            int n = bind(_listensock, (struct sockaddr *)&local, sizeof local);
            if (n < 0)
            {
                logMessage(FATAL, "bind socket error");
                exit(BIND_ERR);
            }
            logMessage(NORMAL, "bind socket success");

             // 3. 设置socket 为监听状态
            n = listen(_listensock, gbacklog);
            if (n < 0)
            {
                logMessage(FATAL, "listen socket error");
                exit(LISTEN_ERR);
            }
            logMessage(NORMAL, "listen socket success");
        }

        void start()
        {
            for(;;)
            {
                // 4. server 获取新链接
                struct sockaddr_in peer;
                bzero(&peer,sizeof peer);
                socklen_t len = sizeof(peer);

                int sock = accept(_listensock,(struct sockaddr*)&peer,&len);
                if(sock<0)
                {
                    logMessage(ERROR,"accept error");
                    continue;;
                }
                logMessage(NORMAL,"accept a new link success, get new sock: %d",sock);

            }
        }
        ~CalServer()
        {
        }

    private:
        int _listensock;
        uint16_t _port;
    };
}